﻿#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

//冒泡排序
//核心思想：两两相邻的元素进⾏⽐较
//void bubble_sort(int arr[], int sz)
//{
//	int i = 0;
//	for (i = 0; i < sz - 1 ; i++)
//	{
//		int j = 0;
//		for (j = 0; j < sz - 1 - i; j++)
//		{
//			if (arr[j] > arr[j + 1])    //注意这里数组的变量，之前写成i了，导致失败
//			{
//				int tmp = 0;
//				tmp = arr[j];
//				arr[j] = arr[j + 1];
//				arr[j + 1] = tmp;
//			}
//		}
//	}
//}
//
//void printf_arr(int arr[],int sz)
//{
//	int i = 0;
//	for (int  i = 0; i < sz ; i++)
//	{
//		printf("%d ", arr[i]);
//	}
//	printf("\n");
//}
//int main()
//{
//	int arr[] = { 5,4,23,2,3,56,7,9,0 };
//	int sz = sizeof(arr) / sizeof(arr[0]);
//	printf_arr(arr,sz);
//	bubble_sort(arr, sz);
//	printf_arr(arr, sz);
//	return 0;
//}




//
////优化，当一个数组是基本排序完的时候，减少排序次数
//void bubble_sort(int arr[], int sz)
//{
//	int i = 0;
//	for (i = 0; i < sz - 1; i++)
//	{
//		int flag = 0;       
//		int j = 0;
//		for (j = 0; j < sz - 1 - i; j++)
//		{
//			if (arr[j] > arr[j + 1])
//			{
//				flag = 1;				//标志着发生交换
//				int tmp = 0;
//				tmp = arr[j];
//				arr[j] = arr[j + 1];
//				arr[j + 1] = tmp;
//				
//			}
//
//		}
//		if (flag == 0)
//			break;
//	}
//}
//
//void printf_arr(int arr[], int sz)
//{
//	int i = 0;
//	for (int i = 0; i < sz; i++)
//	{
//		printf("%d ", arr[i]);
//	}
//	printf("\n");
//}
//int main()
//{
//	int arr[] = { 5,4,23,2,3,56,7,9,0 };
//	int sz = sizeof(arr) / sizeof(arr[0]);
//	printf_arr(arr, sz);
//	bubble_sort(arr, sz);
//	printf_arr(arr, sz);
//	return 0;
//}




//二级指针 存的是一级指针变量的地址 
//这么理解
//       * 代表它是个地址，而int 是地址所指向的变量类型是int
//   而二级指针    *同样指的是它是个地址，而 int* 是地址所指向的变量类型为int*
//int main()
//{
//	int a = 10;
//	int* pa = &a;
//	int** ppa = &pa;
//	**ppa = 200;      //二级指针解引用
//}

//可理解为抽屉跟钥匙之间的关系


//学习指针时要有类比的思想、
//字符数组 == 存放字符的数组
//
//指针数组 == 存放指针（指针变量）的数组




//用指针数组模拟二维数组
//int main()
//{
//	int arr1[] = { 1,2,3,4,5 };
//	int arr2[] = { 2,3,4,5,6 };
//	int arr3[] = { 3,4,5,6,7 };
//	//数组名是数组⾸元素的地址，类型是int*的，就可以存放在parr数组中
//
//		int* parr[3] = { arr1, arr2, arr3 };
//	int i = 0;
//	int j = 0;
//	for (i = 0; i < 3; i++)
//	{
//		for (j = 0; j < 5; j++)
//		{
//			printf("%d ", parr[i][j]);  //先找出 parr[i] == arr[] , 然后选择 j  最后就变成arr[][]
//		}
//		printf("\n");
//	}
//	return 0;
//}


// parr[i]是访问parr数组的元素，parr[i]找到的数组元素指向了整型⼀维数组，parr[i][j]就是整型⼀维数组中的元素。
//上述的代码模拟出⼆维数组的效果，实际上并⾮完全是⼆维数组，因为每⼀⾏并⾮是连续的。





//指针第四部分
 

//字符指针变量
//一般使用方法
//int main()
//{
//	char ch = 'w';
//	char* pc = &ch;
//	*pc = 'w';
//	return 0;
// }

//int main()
//{
//
//	//int arr[] = { 1,23,4,5 };
//	//int* p = arr;
//	//这里p指向了arr数组，实际上是p指向了arr数组的首元素
//
//
//
//	const char* pstr = "hello.";//这⾥是把⼀个字符串放到pstr指针变量⾥了吗？
//								//实际上，上⾯代码的意思是把⼀个常量字符串的⾸字符h的地址存放到指针变量中
//								//常量字符串实际上也可以类比数组，类似首元素地址
////const保护 *p
//		printf("%s\n", pstr);
//	return 0;
// }


//常量字符串放在内存的只读数据区
//int main()
//{
//	char str1[] = "hello bit.";
//	char str2[] = "hello bit.";         
//	const char* str3 = "hello bit.";
//	const char* str4 = "hello bit.";
//	if (str1 == str2)  //比较的是地址   字符串比内容得用strcmp()
//		printf("str1 and str2 are same\n");//1
//	else
//		printf("str1 and str2 are not same\n");//2
//	if (str3 == str4)
//		printf("str3 and str4 are same\n");//3
//	else
//		printf("str3 and str4 are not same\n");//4
//	return 0;
//}
//这⾥str3和str4指向的是⼀个同⼀个常量字符串。C/C++会把常量字符串存储到单独的⼀个内存区域，
//当⼏个指针指向同⼀个字符串的时候，他们实际会指向同⼀块内存。但是⽤相同的常量字符串去初始
//化不同的数组的时候就会开辟出不同的内存块。所以str1和str2不同，str3和str4相同。



//打印字符串的不同方法，小练习
//int main()
//{
//	const char* ps = "hello";
//	printf("%s\n", ps);
//	while (*ps != '\0')
//	{
//		printf("%c", *ps);
//		ps++;
//	}
//
//
//	return 0;
//}





//数组指针变量


//类比整型指针
//字符指针

//即存放的是数组的地址，指向的就是数组了